﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System.Diagnostics;
using System.Windows.Threading;
using Microsoft.Win32;

namespace wiki2doc
{

    public static class ExtensionMethods
    {
        private static Action EmptyDelegate = delegate() { };

        public static void Refresh(this UIElement uiElement)
        {
            uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
        }
    }

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        [Import(typeof(IConfiguration))]
        IConfiguration _conf = null;

        [ImportMany(typeof(IWikiDownload))]
        IEnumerable< Lazy<IWikiDownload, Dictionary<string, object>>> _downloaders = null;

        [ImportMany(typeof(IGenerateDocument))]
        IEnumerable<Lazy<IGenerateDocument, Dictionary<string, object>>> _generators = null;

        const string registry_entrypoint = "Software\\mauricekoster.com\\wiki2doc";

        public MainWindow()
        {

            var  _catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var _container = new CompositionContainer(_catalog);
            _container.ComposeParts(this);

            InitializeComponent();
            stackPanelMain.DataContext = _conf;

            // fill combo of wiki types with available IWikiDownload exports
            foreach (var lazythingy in _downloaders)
            {
                cmbWikiType.Items.Add( lazythingy.Metadata["Name"] );
            }

            foreach (var lazy_gen in _generators)
            {
                MenuItem mnu = new MenuItem();
                mnu.Header = lazy_gen.Metadata["MenuText"];
                mnu.Tag = lazy_gen;
                mnu.Click += mnuGenerate_Click;

                mnuGenerate.Items.Add(mnu);
                
            }

            using (var _reg = Registry.CurrentUser.CreateSubKey(registry_entrypoint))
            {
                string lastusedconf = _reg.GetValue("LastUsedConf", "").ToString();
                if (lastusedconf != "")
                {
                    _conf.Select(lastusedconf);
                    StatusMessage(String.Format("Configuration {0} loaded.", lastusedconf));
                }
            }

        }

        [Export("StatusMessage")]
        public void StatusMessage(string msg)
        {
            // statusBar1
            Debug.WriteLine("Log: " + msg);
            txtStatusText1.Text = msg;
            txtStatusText1.Refresh();
        }

        private void mnuOpen_Click(object sender, RoutedEventArgs e)
        {
            stackPanelMain.DataContext = null;
            var lastused = _conf.Select();
            using (var _reg = Registry.CurrentUser.CreateSubKey(registry_entrypoint))
            {
                _reg.SetValue("LastUsedConf", lastused);
            }
            stackPanelMain.DataContext = _conf;
        }
        private void mnuSave_Click(object sender, RoutedEventArgs e)
        {
            _conf.Store();
        }

        private void mnuGenerate_Click(object sender, RoutedEventArgs e)
        {
            
            // 1st download wiki content
            var _wiki = cmbWikiType.SelectedValue;
            if (_wiki == null) return;
            if (_wiki.Equals("")) return;

            var _downloader = _downloaders
                .Where(l => _wiki.Equals( l.Metadata["Name"].ToString() ) )
                .FirstOrDefault();

            if (_downloader == null)
            {
                MessageBox.Show("No downloader found. (Wiki type set?)");
                return;
            }

            List<string> topics;
            try
            {
                topics = _downloader.Value.Download(_conf);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Something went wrong : " + ex.Message, "wiki2doc");
                return;
            }


            var _generator = ((MenuItem)sender).Tag as Lazy<IGenerateDocument, Dictionary<string, object>>;

            string templatePath = "";
            // templatePath from registry
            
            using ( var _reg = Registry.CurrentUser.CreateSubKey(registry_entrypoint) )
            {
                templatePath = _reg.GetValue("TemplatePath", "").ToString();
            }

            // templatePath from location of executable
            if (templatePath == "" )
            {
                templatePath = AppDomain.CurrentDomain.BaseDirectory + @"Template";
            }
            _generator.Value.Generate( topics, _conf, templatePath);

        }

        private void mnuClose_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        

        
    }
}
